home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
BBS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-08
|
45KB
|
2,139 lines
/* Bulletin Board System */
/* @(#) $Header: bbs.c,v 2.40(WNOS) 92/11/25 12:30:00 deyke Exp $ */
/*
* This file is based on the original WAMPES file 'bbs.c' from DK5SG
* ported to WNOS - DB3FL.911209
*/
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <dir.h>
#include <io.h>
#include "global.h"
#include "config.h"
#ifdef MAILBOX
#include "socket.h"
#include "smtp.h" /* for 'Days' and 'Months' */
#include "files.h"
#include "dirutil.h"
#include "bbs.h"
#include "server.h"
static char *FInfo = NULLCHAR;
static char *FNic = NULLCHAR;
static char *MidSuffix = "@bbs.net";
static char SendMsg[] = "Sending message to %s.\n";
static char *myhostname = NULLCHAR;
static char *MYHOSTNAME = NULLCHAR;
static int len_myhostname = 0;
static int len_MYHOSTNAME = 0;
static char BBSversion[] = "DK5SG-BBS Revision: WNOS_C(2.40) 93/07/08";
static char Entermsg[] = "Enter message (terminate with ^Z or ***END):\n";
static char Indexfile[] = "index";
static char Nosuchmsg[] = "No such Msg '%s'\n";
static char errstr[] = "The '%s' option requires an argument. Type '? %s' for help.\n";
static char Userstr[] = "\nUser: %s\nName: %s\nMyBBS: %s\nLast logout: %s\n\n";
static int fdindex = -1;
static int Lock = 0;
static int BbsUser = 0;
static int32 index_len = sizeof(struct index);
static unsigned uindex_len = sizeof(struct index);
static unsigned uinfo_len = sizeof(struct userinfo);
#undef DEBUG
#ifdef DEBUG
#define errorstop(error) tprintf("BBS-Error %d\n",error)
#else
#define errorstop(error)
#endif
static struct user * near get_seq __ARGS((char *username,int flag));
static void near cleanup __ARGS((struct user *user));
static void near delete_command __ARGS((struct user *user));
static void near dir_command __ARGS((struct user *user));
static void near f_command __ARGS((struct user *user));
static void near help_command __ARGS((struct user *user));
static void near info_command __ARGS((struct user *user));
static void near list_command __ARGS((struct user *user));
static void near mybbs_command __ARGS((struct user *user));
static void near name_command __ARGS((struct user *user));
static void near quit_command __ARGS((struct user *user));
static void near read_command __ARGS((struct user *user));
static void near reply_command __ARGS((struct user *user));
static void near send_command __ARGS((struct user *user));
static void near status_command __ARGS((struct user *user));
static void near user_command __ARGS((struct user *user));
static void near xcrunch_command __ARGS((struct user *user));
static struct cmdtable {
char *name;
void near (*func) __ARGS((struct user *user));
int argc;
int level;
} cmdtable[] = {
"?", help_command, 0, USER,
"bye", quit_command, 0, USER,
"delete", delete_command, 2, USER,
"dir", dir_command, 0, USER,
"erase", delete_command, 2, USER,
"exit", quit_command, 0, USER,
"help", help_command, 0, USER,
"info", info_command, 0, USER,
"kill", delete_command, 2, USER,
"list", list_command, 2, USER,
"mybbs", mybbs_command, 2, USER,
"name", name_command, 2, USER,
"quit", quit_command, 0, USER,
"read", read_command, 2, USER,
"reply", reply_command, 2, USER,
"send", send_command, 2, USER,
"status", status_command, 0, USER,
"user", user_command, 2, USER,
"xcrunch", xcrunch_command, 0, ROOT,
"f>", f_command, 0, BOX,
"sb", send_command, 2, BOX,
"sp", send_command, 2, BOX,
0, 0, 0, 0,
};
static char * near
getarg(char *line,int all)
{
char *arg;
static char *p;
if(line) {
p = line;
}
while(isspace(uchar(*p))) {
p++;
}
if(all) {
return p;
}
arg = p;
while(*p && !isspace(uchar(*p))) {
p++;
}
if(*p) {
*p++ = '\0';
}
return arg;
}
static int near
getstring(struct user *user)
{
int len = -1;
usflush(user->s);
if((len = recvline(user->s,user->line,LINELEN)) < 0) {
return 0;
}
return len;
}
static void near
wait_for_prompt(struct user *user)
{
int l = 0;
do {
if(!getstring(user)) {
return;
}
rip(user->line);
l = strlen(user->line);
} while (!l || user->line[l-1] != '>');
}
static char * near
strtrim(char *s)
{
char *p;
for(p = s; *p; p++) ;
while(--p >= s && isspace(uchar(*p))) ;
p[1] = 0;
return s;
}
static char * near
strcasepos(char *str, char *pat)
{
char *s, *p;
for(; ; str++) {
for(s = str, p = pat; ; ) {
if(!*p) {
return str;
}
if(!*s) {
return 0;
}
if(tolower(uchar(*s++)) != tolower(uchar(*p++))) {
break;
}
}
}
}
static int near
callvalid(char *call)
{
int d = 0, l = strlen(call);
if(l < 2 || l > 6) {
return 0;
}
if(isdigit(uchar(call[0])) && isdigit(uchar(call[1]))) {
return 0;
}
if(!(isdigit(uchar(call[1])) || isdigit(uchar(call[2])))) {
return 0;
}
if(!isalpha(uchar(call[l-1]))) {
return 0;
}
for(; *call; call++) {
if(!isalnum(uchar(*call))) {
return 0;
}
if(isdigit(uchar(*call))) {
d++;
}
}
if(d < 1 || d > 2) {
return 0;
}
return 1;
}
static int near
check_eom(char *s,int flag)
{
if((!flag
&& *s == '\032')
|| strcmp(s,".\n") == 0
|| stricmp(s,"***end\n") == 0
|| stricmp(s,"/ex\n") == 0) {
if(flag) {
*s = ' ';
}
return 1;
}
return 0;
}
static int
make_parent_directories(char *filename)
{
char dirname[MAXPATH], *p;
sprintf(dirname,"%.*s",MAXPATH-1,filename);
if((p = strrchr(dirname,'/')) != NULLCHAR) {
*p = '\0';
}
if(mkdir(dirname) == 0) {
return 0;
}
make_parent_directories(dirname);
return mkdir(dirname);
}
static char * near
getfilename(int32 mesg)
{
static char buf[MAXPATH + 12];
sprintf(buf,"%s/%02lx/%02lx/%02lx/%02lx",
BBSwrkdir,
((mesg >> 24) & 0xff),
((mesg >> 16) & 0xff),
((mesg >> 8) & 0xff),
((mesg ) & 0xff));
return buf;
}
static int near
get_index(int32 n,struct index *index)
{
int32 i1 = 0, i2 = 0, im = 0, imt = 0, pos = 0;
lseek(fdindex,0,SEEK_SET);
if(read(fdindex,index,uindex_len) != uindex_len) {
errorstop(1);
return 0;
}
if(n == index->mesg) {
return 1;
}
if(n < index->mesg) {
return 0;
}
if((pos = lseek(fdindex,-index_len,SEEK_END)) < 0) {
errorstop(2);
return 0;
}
i2 = pos / index_len;
if(read(fdindex,index,uindex_len) != uindex_len) {
errorstop(3);
return 0;
}
if(n == index->mesg) {
return 1;
}
if(n > index->mesg) {
return 0;
}
while(i1 + 1 < i2) {
im = (i1 + i2) / 2;
imt = im * index_len;
if(lseek(fdindex,imt,SEEK_SET) < 0) {
errorstop(4);
return 0;
}
if(read(fdindex,index,uindex_len) != uindex_len) {
errorstop(5);
return 0;
}
if(n == index->mesg) {
return 1;
}
if(n > index->mesg) {
i1 = im;
} else {
i2 = im;
}
}
return 0;
}
static int near
read_allowed(struct index *index,struct user *user)
{
switch(index->flag) {
case DELETED:
return 0;
case PRIVATE:
case NORMAL:
if(user->level != ROOT) {
if(stricmp(user->name,index->to) && stricmp(user->name,index->from)) {
return 0;
}
}
case BULLETIN:
if(user->level == ROOT) {
return 1;
}
if(stricmp("THEBOX",index->at) == 0) {
return 0;
}
case NEWS:
return 1;
}
return 0;
}
static char * near
get_user_from_path(char *path)
{
char *cp;
if((cp = strrchr(path,'!')) == NULLCHAR) {
return path;
}
return cp + 1;
}
static char * near
get_host_from_path(char *path)
{
char *cp;
static char tmp[80];
strcpy(tmp,path);
if((cp = strrchr(tmp,'!')) == NULLCHAR) {
return myhostname;
}
*cp = '\0';
if((cp = strrchr(tmp,'!')) == NULLCHAR) {
return tmp;
}
return cp + 1;
}
static char * near
get_host_from_header(char *line)
{
char *p, *q, buf[80];
if(*line == 'R'
&& line[1] == ':'
&& ((p = strchr(strcpy(buf,line),'@')) != NULLCHAR)) {
p++;
while(*p == ':' || isspace(uchar(*p))) {
p++;
}
for(q = p; isalnum(uchar(*q)); q++) ;
*q = 0;
return p;
}
return NULLCHAR;
}
static int near
msg_uniq(char *bid)
{
struct index pi;
int32 validdate = currtime - 90 * DAYS;
if(lseek(fdindex,0,SEEK_SET) != 0) {
errorstop(6);
return 0;
}
while(read(fdindex,&pi,uindex_len) == uindex_len) {
if(pi.date >= validdate && stricmp(pi.bid,bid) == 0) {
return 0;
}
}
return 1;
}
static int32 near
send_to_bbs(struct mail *mail)
{
int32 mesg = 0;
if(!*mail->subject) {
return 0;
}
semwait(&Lock,1);
if(msg_uniq(mail->bid) == 1) {
FILE *fp;
struct strlist *p;
struct index index;
if(lseek(fdindex,-index_len,SEEK_END) < 0) {
mesg = 0;
} else {
if(read(fdindex,&index,uindex_len) != uindex_len) {
errorstop(7);
goto quit;
}
mesg = index.mesg;
}
memset(&index,0,uindex_len);
index.mesg = ++mesg;
index.date = mail->date;
index.lifetime_h = (mail->lifetime + 1) >> 8;
index.lifetime_l = (mail->lifetime + 1) & 0x0F;
strcpy(index.bid,mail->bid);
sprintf(index.subject,"%.*s",LEN_SUBJECT,mail->subject);
sprintf(index.to,"%.*s",LEN,get_user_from_path(mail->to));
strupr(index.to);
sprintf(index.at,"%.*s",LEN,get_host_from_path(mail->to));
strupr(index.at);
sprintf(index.from,"%.*s",LEN,get_user_from_path(mail->from));
strupr(index.from);
sprintf(index.from_at,"%.*s",LEN,get_host_from_path(mail->from));
strupr(index.from_at);
index.flag = mail->flag;
index.size = 0;
if((fp = Fopen(getfilename(index.mesg),WRITE_TEXT,0,0)) == NULLFILE) {
make_parent_directories(getfilename(index.mesg));
if((fp = Fopen(getfilename(index.mesg),WRITE_TEXT,0,1)) == NULLFILE) {
errorstop(10);
goto quit;
}
}
if(strcmp(index.to,"E") != 0 && strcmp(index.to,"M") != 0) {
for (p = mail->head; p; p = p->next) {
fputs(p->str,fp);
index.size += (strlen(p->str) + 1);
}
}
Fclose(fp);
if(lseek(fdindex,0,SEEK_END) < 0) {
errorstop(11);
goto quit;
}
if(write(fdindex,&index,uindex_len) != uindex_len) {
errorstop(12);
goto quit;
}
}
quit:
semrel(&Lock);
return mesg;
}
static void near
send_to_mail(struct mail *mail)
{
FILE *fp;
char *cp, line[LINELEN];
struct strlist *p;
int32 msg = get_msgid();
sprintf(line,"%s/%ld.txt",Mailqdir,msg);
if((fp = Fopen(line,WRITE_TEXT,0,1)) != NULLFILE) {
if(strchr(mail->from,'!') != NULLCHAR) {
char *tmp = strxdup(mail->from);
*mail->from = '\0';
while((cp = strrchr(tmp,'!')) != NULLCHAR) {
*cp++ = '\0';
strcat(mail->from,cp);
strcat(mail->from,"%");
}
strcat(mail->from,tmp);
xfree(tmp);
}
if((cp = strrchr(mail->from,'%')) != NULLCHAR) {
*cp = '@';
}
if(strchr(mail->to,'!') != NULLCHAR) {
char *tmp = strxdup(mail->to);
*mail->to = '\0';
while((cp = strrchr(tmp,'!')) != NULLCHAR) {
*cp++ = '\0';
strcat(mail->to,cp);
strcat(mail->to,"%");
}
strcat(mail->to,tmp);
xfree(tmp);
}
if((cp = strrchr(mail->to,'%')) != NULLCHAR) {
*cp++ = '@';
}
fprintf(fp,"%sby %s (%s)\n\tid AA%ld; %s",
Hdrs[RECEIVED],Hostname,BBSversion,msg,rfc822_date(&currtime));
fprintf(fp,"%s%s",
Hdrs[DATE],rfc822_date(&mail->date));
fprintf(fp,"%s<%s>\n%s<%s>\n",
Hdrs[MSGID],mail->mid,Hdrs[BULLID],mail->bid);
if(mail->lifetime != -1) {
int32 t = mail->date + (DAYS * mail->lifetime);
fprintf(fp,"%s%s",Hdrs[EXPIRE],rfc822_date(&t));
}
fprintf(fp,"%s%s\n%s%s\n",
Hdrs[FROM],mail->from,Hdrs[TO],mail->to);
if (*mail->subject) {
fprintf(fp,"%s%s\n",Hdrs[SUBJECT],mail->subject);
}
fputc('\n',fp);
for (p = mail->head; p; p = p->next) {
fputs(p->str, fp);
}
Fclose(fp);
sprintf(line,"%s/%ld.wrk",Mailqdir,msg);
if((fp = Fopen(line,WRITE_TEXT,0,1)) != NULLFILE) {
fprintf(fp,"%s\n%s\n\%s\n",cp,mail->from,mail->to);
Fclose(fp);
}
}
}
#ifdef XXX
static void near
send_to_news(struct mail *mail)
{
FILE *fp;
char *fromhost, *pp;
int fd, i;
struct strlist *p;
if (!*mail->subject) return;
if ((fp = fopen("/usr/bin/rnews", "w")) == NULLFILE) _exit(1);
fromhost = get_host_from_path(mail->from);
fprintf(fp,"%s%s@%s%s\n",
Hdrs[FROM],get_user_from_path(mail->from),fromhost,strchr(fromhost, '.') ? "" : ".ampr.org");
fprintf(fp,"%s%s",
Hdrs[DATE],rfc822_date(mail->date));
fprintf(fp,"%sampr.bbs.%s\n",
Hdrs[NEWSGROUPS],get_user_from_path(mail->to));
fprintf(fp,"%s%s\n",
Hdrs[SUBJECT],mail->subject);
fprintf(fp,"%s<%s>\n",
Hdrs[MSGID],mail->mid);
i = strlen(Hostname);
if(!strncmp(mail->from,Hostname,i) && mail->from[i] == '!') {
pp = mail->from + i + 1;
} else {
pp = mail->from;
}
fprintf(fp,"%s%s\n",
Hdrs[PATH],pp);
if (mail->lifetime != -1) {
fprintf(fp,"%s%s",
Hdrs[EXPIRES],rfc822_date(mail->date + DAYS * mail->lifetime));
}
fprintf(fp,"%s%s\n",
Hdrs[DISTRIBUTION],get_host_from_path(mail->to));
fprintf(fp,"%s<%s>\n",
Hdrs[BULLID],mail->bid);
fputc('\n', fp);
p = mail->head;
while (p && p->str[0] == 'R' && p->str[1] == ':')
p = p->next;
while (p
&& (p->str[0] == 'd'
&& p->str[1] == 'e'
&& p->str[2] == ' '
|| p->str[0] == 't'
&& p->str[1] == 'o'
&& p->str[2] == ' '))
p = p->next;
while (p && p->str[0] == 0)
p = p->next;
while (p) {
fputs(p->str, fp);
fputc('\n', fp);
p = p->next;
}
pclose(fp);
_exit(0);
}
#endif
static void near
fix_address(char *addr)
{
char *p1, *p2, tmp[80];
for (p1 = addr; *p1; p1++) {
switch (*p1) {
case '%':
/* case '.': */
*p1 = '@';
break;
case ',':
*p1 = ':';
break;
case '^':
*p1 = '!';
break;
}
}
while(((p1 = strchr(addr,'@')) != NULLCHAR)
&& ((p2 = strchr(p1,':')) != NULLCHAR)) {
*p1 = *p2 = 0;
sprintf(tmp,"%s%s!%s",addr,p1 + 1,p2 + 1);
strcpy(addr,tmp);
}
while((p2 = strrchr(addr,'@')) != NULLCHAR) {
*p2 = 0;
p1 = p2;
while (p1 > addr && *p1 != '!') {
p1--;
}
if(p1 == addr) {
sprintf(tmp,"%s!%s",p2 + 1,addr);
} else {
*p1 = 0;
sprintf(tmp,"%s!%s!%s",addr,p2 + 1,p1 + 1);
}
strcpy(addr, tmp);
}
if(strchr(addr,'!') == NULLCHAR) {
sprintf(tmp,"%s!%s",myhostname,addr);
strcpy(addr,tmp);
}
strlwr(addr);
}
static struct mail * near
alloc_mail(void)
{
struct mail *mail = mxallocw(sizeof(struct mail));
mail->lifetime = -1;
return mail;
}
static void near
free_mail(struct mail *mail)
{
struct strlist *p;
while((p = mail->head) != NULL) {
mail->head = p->next;
xfree(p->str);
xfree(p);
}
xfree(mail);
}
static void near
route_mail(struct mail *mail,struct user *user,int flag)
{
char *cp = NULLCHAR;
struct strlist *p = 0;
/* Set date */
mail->date = currtime;
/* Fix addresses */
fix_address(mail->from);
fix_address(mail->to);
if(mail->flag == NORMAL) {
if(callvalid(get_user_from_path(mail->to))) {
mail->flag = PRIVATE;
} else {
mail->flag = BULLETIN;
}
}
/* Check for bogus mails */
strtrim(mail->subject);
if(((cp = get_host_from_header(mail->subject)) != NULLCHAR && callvalid(cp))) {
goto Done;
}
if(user->level == BOX) {
if((cp = get_user_from_path(mail->to)) == NULLCHAR) {
goto Done;
}
if(strlen(cp) > 1) {
if(!mail->head) {
goto Done;
}
if((cp = get_host_from_header(mail->head->str)) == NULLCHAR
|| stricmp(cp,user->name) == 0) {
goto Done;
}
}
}
/* Set bid */
if(!*mail->bid && *mail->mid) {
int i = 0;
char *cp = mail->mid;
while(*cp != '\0') {
if(!isalnum(*cp)) {
if(!i) {
*cp = '_';
i = 1;
} else {
*cp = '\0';
break;
}
}
cp++;
}
sprintf(mail->bid,"%.12s",mail->mid);
}
if(!*mail->bid) {
sprintf(mail->bid,"%012d",get_msgid());
strncpy(mail->bid,MYHOSTNAME,min(9,len_MYHOSTNAME));
}
strupr(mail->bid);
/* Set mid */
if(!*mail->mid) {
sprintf(mail->mid,"%s%s",mail->bid,MidSuffix);
}
/* Remove message delimiters */
for(p = mail->head; p; p = p->next) {
char *s = p->str;
if(*s == '.' && !s[1]) {
*s = 0;
}
while((cp = strchr(s,'\032')) != NULLCHAR) {
while((cp[0] = cp[1]) != 0) {
cp++;
}
}
check_eom(s,1);
}
/* Call delivery agents */
if(flag == MAIL) {
send_to_mail(mail);
} else {
int32 mesg = send_to_bbs(mail);
if(mesg && (user->info && mesg == (user->info->seq + 1))) {
user->info->seq = mesg;
}
}
Done:
/* Free mail */
free_mail(mail);
}
static void near
append_line(struct mail *mail,char *line)
{
struct strlist *p = mxallocw(sizeof(struct strlist));
p->str = strxdup(line);
if (!mail->head) {
mail->head = p;
} else {
mail->tail->next = p;
}
mail->tail = p;
}
static int near
get_header_value(char *name,char *line,char *value)
{
char *p1, *p2;
while(*name) {
if(tolower(uchar(*name++)) != tolower(uchar(*line++))) {
return 0;
}
}
while(isspace(uchar(*line))) {
line++;
}
while(((p1 = strchr(line, '<')) != NULLCHAR)
&& ((p2 = strrchr(p1, '>')) != NULLCHAR)) {
*p2 = 0;
line = p1 + 1;
}
strcpy(value,line);
return 1;
}
static int near
host_in_header(char *fname, char *host)
{
FILE *fp;
if((fp = Fopen(fname,READ_TEXT,0,1)) != NULLFILE) {
char *p, buf[MAXPATH];
while(fgets(buf,MAXPATH,fp) != NULL) {
if((p = get_host_from_header(buf)) != NULLCHAR
&& stricmp(p,host) == 0) {
Fclose(fp);
return 1;
}
}
Fclose(fp);
}
return 0;
}
#ifdef XXX
static int near
mail_pending(struct user *user)
{
char dirname[MAXPATH];
static int have_mail;
static int32 nexttime = 0;
if(nexttime > currtime) {
return have_mail;
}
nexttime = currtime + 5 * MINUTES;
have_mail = 0;
sprintf(dirname,"%s/%s.lck",Mailspool,user->name);
if(access(dirname,0) == 0) {
have_mail = 1;
}
return have_mail;
}
#endif
static void near
delete_command(struct user *user)
{
char *cp;
semwait(&Lock,1);
getarg(user->line,0);
while(*(cp = getarg(0,0))) {
int32 mesg = 0;
struct index index;
memset(&index,0,uindex_len);
if((mesg = atol(cp)) > 0
&& get_index(mesg,&index)
&& !(index.flag & DELETED)) {
if(user->level == ROOT
|| stricmp(index.from,user->name) == 0
|| stricmp(index.to,user->name) == 0) {
unlink(getfilename(mesg));
index.flag = DELETED;
if(lseek(fdindex,-index_len,SEEK_CUR) < 0) {
errorstop(15);
goto quit;
}
write(fdindex,&index,uindex_len);
usprintf(user->s,"Msg# %d deleted\n", mesg);
} else {
usprintf(user->s,"Msg# %d not deleted: Permission denied\n", mesg);
}
} else {
usprintf(user->s,Nosuchmsg,cp);
}
}
quit:
semrel(&Lock);
}
static int near
dir_print(struct dir_entry *p,int s)
{
int i = 0;
if(p) {
dir_print(p->left,s);
usprintf(s,(i++ % 5) < 4 ? "%5d %-8s" : "%5d %s\n",p->count,p->to);
dir_print(p->right,s);
xfree(p);
}
return i;
}
static void near
dir_command(struct user *user)
{
int cmp = 0;
struct dir_entry *head = 0, *curr = 0, *prev = 0;
struct index pi;
lseek(fdindex,0,SEEK_SET);
while(read(fdindex,&pi,uindex_len) == uindex_len) {
if(read_allowed(&pi,user)) {
for(prev = 0, curr = head; ; ) {
if(!curr) {
curr = mxallocw(sizeof(struct dir_entry));
curr->count = 1;
strcpy(curr->to,pi.to);
if(!prev) {
head = curr;
} else if (cmp < 0) {
prev->left = curr;
} else {
prev->right = curr;
}
break;
}
if((cmp = strcmp(pi.to,curr->to)) == 0) {
curr->count++;
break;
}
prev = curr;
curr = (cmp < 0) ? curr->left : curr->right;
}
}
}
if(dir_print(head,user->s) % 4) {
usputs(user->s,"\n");
}
}
static void near
f_command(struct user *user)
{
FILE *fp;
struct index index;
char line[LINELEN];
int lifetime, do_not_exit = 0;
semwait(&Lock,1);
if(!get_index(user->info->seq,&index)) {
lseek(fdindex,0,SEEK_SET);
}
semrel(&Lock);
while(read(fdindex,&index,uindex_len) == uindex_len) {
if(!(index.flag & DELETED)
&& index.mesg > user->info->seq
&& strnicmp(index.at,MYHOSTNAME,len_MYHOSTNAME) != 0
&& !host_in_header(getfilename(index.mesg),user->name)) {
#ifdef XXX
if(mail_pending(user)) {
return;
}
#endif
do_not_exit = 1;
lifetime = ((index.lifetime_h << 8) & 0xff00) + (index.lifetime_l & 0xff) - 1;
usprintf(user->s,"S %s%s%s < %s%s%s",
index.to,
*index.at ? " @ " : "",
index.at,
index.from,
*index.bid ? " $ " : "",
index.bid);
if(lifetime != -1) {
usprintf(user->s," # %d",lifetime);
}
usputs(user->s,"\n");
if(!getstring(user)) {
return;
}
switch(tolower(*user->line)) {
case 'o':
usprintf(user->s,"%s\n",*index.subject ? index.subject : "no subject");
if(strcmp(index.to,"E") == 0 || strcmp(index.to,"M") == 0) {
usputs(user->s,"\n");
} else {
struct tm *tm = gmtime(&index.date);
usprintf(user->s,"R:%02d%02d%02d/%02d%02dz @:%s.%s [%s]\n",
tm->tm_year,
tm->tm_mon + 1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
MYHOSTNAME,
FNic ? FNic : MYHOSTNAME,
FInfo ? FInfo : Version);
if((fp = Fopen(getfilename(index.mesg),READ_TEXT,0,1)) == NULLFILE) {
return;
}
while(fgets(line,LINELEN,fp) != NULL) {
usputs(user->s,line);
}
Fclose(fp);
}
usputs(user->s,"\032\n");
case 'n':
wait_for_prompt(user);
break;
default:
return;
}
}
if(user->info->seq < index.mesg) {
user->info->seq = index.mesg;
}
}
if(do_not_exit) {
usputs(user->s,"F");
} else {
return;
}
}
static void near
help_command(struct user *user)
{
char *cp;
getarg(user->line,0);
if(!(*(cp = getarg(0,1)))) {
int i;
struct cmdtable *cmdp;
usputs(user->s,"Commands may be abbreviated. Commands are:\n");
for (i = 0, cmdp = cmdtable; cmdp->name; cmdp++) {
if (user->level >= cmdp->level) {
usprintf(user->s,(i++ % 5) < 4 ? "%-15.15s" : "%s\n", cmdp->name);
}
}
if (i % 5) {
usputs(user->s,"\n");
}
} else {
gethelp(9980,user->s,cp);
}
}
static void near
info_command(struct user *user)
{
FILE *fp;
char buf[LINELEN];
usprintf(user->s,"%s\n",BBSversion);
sprintf(buf,"%s/bbs.inf",BBSwrkdir);
if((fp = Fopen(buf,READ_TEXT,0,0)) != NULLFILE) {
while(fgets(buf,LINELEN,fp) != NULL) {
usputs(user->s,buf);
}
Fclose(fp);
}
}
#define nextarg(name) \
if(!*(cp = getarg(0,0))) { \
nname = name; \
goto quit; \
} \
static void near
list_command(struct user *user)
{
char *at = 0, *bid = 0, *from = 0, *mfrom = 0, *subject = 0, *to = 0, *cp, *nname = "";
int arg = 2, found = 0, len, update_seq = 0;
int32 count = 999999L, max = 999999L, min = 1;
struct index index;
getarg(user->line,0);
while(*(cp = getarg(0,0))) {
len = strlen(strlwr(cp));
if(!strcmp("$", cp) || !strncmp("bid", cp, len)) {
nextarg("BID");
bid = strupr(cp);
} else if (!strcmp("<", cp) || !strncmp("from", cp, len)) {
nextarg("FROM");
from = strupr(cp);
} else if (!strcmp(">", cp) || !strncmp("to", cp, len)) {
nextarg("TO");
to = strupr(cp);
} else if (!strcmp("@", cp) || !strncmp("at", cp, len)) {
nextarg("AT");
at = strupr(cp);
} else if (!strncmp("count", cp, len)) {
nextarg("COUNT");
count = atol(cp);
} else if (!strncmp("new", cp, len)) {
min = user->info->seq + 1;
update_seq = (arg++ == 2 && user->level != BOX);
} else if (!strncmp("max", cp, len)) {
nextarg("MAX");
max = atol(cp);
} else if (!strncmp("min", cp, len)) {
nextarg("MIN");
min = atol(cp);
} else if (!strncmp("subject", cp, len)) {
nextarg("SUBJECT");
subject = cp;
} else if (!strncmp("mfrom", cp, len)) {
nextarg("MFROM");
mfrom = strupr(cp);
} else {
to = strupr(cp);
}
}
if(lseek(fdindex,-index_len,SEEK_END) >= 0) {
int32 tindex_len = 2 * index_len;
for (; ; ) {
if(read(fdindex,&index,uindex_len) != uindex_len) {
errorstop(20);
return;
}
if(index.mesg < min) {
break;
}
if(index.mesg <= max
&& read_allowed(&index,user)
&& (!bid || !strcmp(index.bid,bid))
&& (!from || strstr(index.from,from))
&& (!to || strstr(index.to,to))
&& (!at || strstr(index.at,at))
&& (!mfrom || strstr(index.from_at,mfrom))
&& (!subject || strcasepos(index.subject,subject))) {
if(!found) {
usputs(user->s," Msg# Size To @BBS From Date Subject\n");
found = 1;
}
usprintf(user->s,"%6ld%6ld %-9.9s%c%-9.9s %-9.9s %-7.7s %.28s\n",
index.mesg,
index.size,
index.to,
*index.at ? '@' : ' ',
index.at,
index.from,
timestr(index.date),
index.subject);
if(update_seq && user->info->seq < index.mesg) {
user->info->seq = index.mesg;
}
if(--count <= 0) {
break;
}
}
if(lseek(fdindex,-tindex_len,SEEK_CUR) < 0) {
break;
}
}
}
if(!found) {
usputs(user->s,update_seq
? "No new messages since last LIST NEW command.\n"
: "No matching message found.\n");
}
return;
quit:
user->errors++;
usprintf(user->s,errstr,nname,"LIST");
return;
}
#undef nextarg
static void near
mybbs_command(struct user *user)
{
char *cp;
getarg(user->line,0);
cp = getarg(0,0);
if(!callvalid(strupr(cp))) {
usprintf(user->s,Invcall,cp);
return;
}
if(strcmp(user->info->mybbs,cp) != 0) {
struct mail *mail = alloc_mail();
sprintf(user->info->mybbs,"%.27s",cp);
strcpy(mail->from,user->name);
strcpy(mail->to,"m@thebox");
sprintf(mail->subject,"%s %ld",cp,currtime);
append_line(mail,"");
route_mail(mail,user,BBS);
}
usprintf(user->s,"Setting MYBBS to %s.\n",cp);
}
static void near
name_command(struct user *user)
{
char *cp;
getarg(user->line,0);
cp = getarg(0,0);
*cp = toupper(*cp);
sprintf(user->info->name,"%.27s",cp);
}
static void near
quit_command(struct user *user)
{
user->level = CLOSED;
}
static void near
read_command(struct user *user)
{
char *cp;
getarg(user->line,0);
while(*(cp = getarg(0,0))) {
FILE *fp;
char *p, buf[LINELEN], path[LINELEN];
struct index index;
int32 mesg = 0;
int inheader;
memset(&index,0,uindex_len);
semwait(&Lock,1);
if((mesg = atol(cp)) > 0
&& get_index(mesg,&index)
&& read_allowed(&index,user)) {
semrel(&Lock);
if((fp = Fopen(getfilename(mesg),READ_TEXT,0,1)) == NULLFILE) {
return;
}
usprintf(user->s,"Msg# %ld To: %s%s%s From: %s @%s Date: %s\n",
index.mesg,
index.to,
*index.at ? " @" : "",
index.at,
index.from,
index.from_at,
timestr(index.date));
if(*index.subject) {
usprintf(user->s,"%s%s\n",Hdrs[SUBJECT],index.subject);
}
if(*index.bid) {
usprintf(user->s,"%s%s\n",Hdrs[BULLID],index.bid);
}
*path = 0;
inheader = 1;
while(fgets(buf,LINELEN,fp) != NULL) {
if(inheader) {
if((p = get_host_from_header(buf)) != NULLCHAR) {
strcat(path,*path ? "!" : Hdrs[PATH]);
strcat(path,p);
continue;
}
if(*path) {
usprintf(user->s,"%s\n",path);
}
inheader = 0;
usputs(user->s,"\n");
}
usputs(user->s,buf);
}
done:
Fclose(fp);
usputs(user->s,"\n");
} else {
semrel(&Lock);
usprintf(user->s,Nosuchmsg,cp);
}
}
}
static void near
reply_command(struct user *user)
{
char *cp, *host = 0, *mesgstr = 0, *p = 0;
int all = 0;
int32 mesg = 0;
struct index index;
struct mail *mail;
getarg(user->line,0);
while(*(cp = getarg(0,0))) {
if(stricmp(cp,"all") == 0) {
all = 1;
} else {
mesg = atol(mesgstr = cp);
}
}
if(!mesgstr) {
usputs(user->s,"No message number specified.\n");
return;
}
memset(&index,0,uindex_len);
semwait(&Lock,1);
if(mesg < 1 || !get_index(mesg,&index) || !read_allowed(&index,user)) {
usprintf(user->s,Nosuchmsg,mesgstr);
semrel(&Lock);
return;
}
semrel(&Lock);
mail = alloc_mail();
strcpy(mail->from,user->name);
if(all) {
strcpy(mail->to,index.to);
if(*index.at) {
strcat(mail->to,"@");
strcat(mail->to,index.at);
}
} else {
FILE *fp;
char *cp, line[MAXPATH];
sprintf(mail->to,"%s@%s",index.from,index.from_at);
if((cp = strchr(mail->to,' ')) != NULLCHAR) {
*cp = '\0';
}
if(strcasepos(index.from_at,"BBS") != 0) {
if((fp = Fopen(getfilename(mesg),READ_TEXT,0,1)) == NULLFILE) {
free_mail(mail);
return;
}
for(host = 0; fgets(line,MAXPATH,fp); host = p) {
if((p = get_host_from_header(line)) == NULLCHAR) {
break;
}
}
Fclose(fp);
if(host) {
strcat(mail->to,"@");
strcat(mail->to,host);
}
}
}
strlwr(mail->to);
for(p = index.subject; ; ) {
while(isspace(*p)) {
p++;
}
if(strnicmp(p,"Re:",3) != 0) {
break;
}
p += 3;
}
usprintf(user->s,"%s%s\n",Hdrs[TO],mail->to);
sprintf(mail->subject,"Re: %s",p);
usprintf(user->s,"%s%s\n",Hdrs[SUBJECT],mail->subject);
usputs(user->s,Entermsg);
for(; ; ) {
if(!getstring(user)) {
free_mail(mail);
return;
}
if(check_eom(user->line,0)) {
break;
}
append_line(mail,user->line);
if(strchr(user->line,'\032')) {
break;
}
if(strchr(user->line,'\001')) {
free_mail(mail);
return;
}
}
usprintf(user->s,SendMsg,mail->to);
route_mail(mail,user,MAIL);
}
#define nextarg(name) \
if(isalnum(*(cp + 1))) { \
cp++; \
} else if(!*(cp = getarg(0,0))) { \
nname = name; \
goto quit1; \
}
static void near
send_command(struct user *user)
{
char *cp = getarg(user->line,0), *p, at[80], path[80], *nname = "";
int check_header = 1;
struct mail *mail = alloc_mail();
if(user->level == BOX) {
switch(tolower(*(cp + 1))) {
default:
mail->flag = PRIVATE;
break;
case 'b':
mail->flag = BULLETIN;
break;
}
}
*at = *path = '\0';
while(*(cp = getarg(0,0))) {
if (*cp == '#') {
nextarg("#");
mail->lifetime = atoi(cp);
} else if (*cp == '$') {
nextarg("$");
strcpy(mail->bid, cp);
} else if (*cp == '<') {
nextarg("<");
strcpy(mail->from, cp);
} else if (*cp == '>') {
nextarg(">");
strcpy(mail->to, cp);
} else if (*cp == '@') {
nextarg("@");
strcpy(at, cp);
} else {
strcpy(mail->to, cp);
}
}
if(!*mail->to || (user->level == USER && !mail->to[1])) {
user->errors++;
usputs(user->s,"No or invalid recipient specified\n");
goto quit;
}
if(*at) {
strcat(mail->to,"@");
strcat(mail->to,at);
}
strlwr(mail->to);
if(!*mail->from || user->level < BOX) {
strcpy(mail->from,user->name);
}
if(*mail->bid) {
mail->bid[LEN_BID - 1] = 0;
strupr(mail->bid);
if(!msg_uniq(mail->bid)) {
usputs(user->s,"No\n");
goto quit;
}
}
usputs(user->s,(user->level == BOX) ? "OK\n" : "Enter subject: ");
if(!getstring(user)) {
goto quit;
}
strcpy(mail->subject,user->line);
strtrim(mail->subject);
if(!*mail->subject && user->level != BOX) {
user->errors++;
usputs(user->s,"No subject specified.\n");
goto quit;
}
if(user->level != BOX) {
usputs(user->s,Entermsg);
}
for (; ; ) {
if(!getstring(user)) {
goto quit;
}
if(check_eom(user->line,0)) {
break;
}
if(!(check_header && user->line[0] == ' ' && user->line[1] == '[')) {
append_line(mail,user->line);
if (check_header) {
if((p = get_host_from_header(user->line)) != NULLCHAR) {
if (*path) {
strcat(path, "!");
}
strcat(path, p);
} else if (*path) {
check_header = 0;
}
}
}
if(strchr(user->line,'\032')) {
break;
}
if(strchr(user->line,'\001')) {
goto quit;
}
}
/* Insert customised signature if one is found */
if(user->level != BOX) { /* not a forwarding BBS */
FILE *fp;
sprintf(user->line,"%s/%s.sig",Signature,user->name);
if((fp = Fopen(user->line,READ_TEXT,0,0)) != NULLFILE) {
while(fgets(user->line,LINELEN,fp) != NULLCHAR) {
append_line(mail,user->line);
}
Fclose(fp);
}
}
if(*path) {
strcpy(user->line,mail->from);
sprintf(mail->from,"%s!%s",path,user->line);
}
if(user->level != BOX) {
usprintf(user->s,SendMsg,mail->to);
}
route_mail(mail,user,MAIL);
return;
quit1:
user->errors++;
usprintf(user->s,errstr,nname,"SEND");
quit:
free_mail(mail);
}
#undef nextarg
static void near
status_command(struct user *user)
{
struct index pi;
int32 active = 0, crunchok = 0, deleted = 0, highest = 0;
int32 new = 0, readable = 0, validdate = currtime - 90 * DAYS;
usputs(user->s,BBSversion);
usprintf(user->s,Userstr,
user->name,user->info->name,user->info->mybbs,timestr(user->info->time));
lseek(fdindex,0,SEEK_SET);
while(read(fdindex,&pi,uindex_len) == uindex_len ) {
highest = pi.mesg;
if(pi.flag & DELETED) {
deleted++;
if(!*pi.bid || pi.date < validdate) {
crunchok++;
}
} else {
active++;
if(read_allowed(&pi,user)) {
readable++;
if(pi.mesg > user->info->seq) {
new++;
}
}
}
}
usprintf(user->s,
"%6ld Highest message number\n"
"%6ld Active messages\n"
"%6ld Readable messages\n"
"%6ld Last message listed\n"
"%6ld New messages\n",
highest,
active,
readable,
user->info->seq,
new);
if(user->level == ROOT) {
usprintf(user->s,
"%6ld Deleted messages\n"
"%6ld Messages may be crunched\n",
deleted,
crunchok);
}
}
static void near
user_command(struct user *user)
{
char *cp;
struct user *u;
getarg(user->line,0);
cp = getarg(0,1);
u = get_seq(strupr(cp),1);
BbsUser++;
if(u->info->seq == 0 && *u->info->mybbs == '\0') {
usprintf(user->s,"User %s not known.\n",cp);
} else {
usprintf(user->s,Userstr,
u->name,u->info->name,u->info->mybbs,timestr(u->info->time));
}
cleanup(u);
}
static void near
xcrunch_command(struct user *user)
{
int f, wflag = 0;
char tmpfile[MAXPATH], tempfile[MAXPATH];
struct index index;
sprintf(tempfile,"%s/%s",BBSwrkdir,Indexfile);
sprintf(tmpfile,"%s.tmp",tempfile);
semwait(&Lock,1);
if((f = open(tmpfile,O_WRONLY | O_CREAT | O_BINARY,S_IREAD | S_IWRITE)) < 0) {
goto quit;
}
lseek(fdindex,0,SEEK_SET);
memset(&index,0,uindex_len);
while(read(fdindex,&index,uindex_len) == uindex_len) {
wflag = 1;
if(!(index.flag & DELETED)
|| *index.bid && index.date >= (currtime - 90 * DAYS)) {
if(write(f,&index,uindex_len) != uindex_len) {
goto quit;
}
wflag = 0;
}
memset(&index,0,uindex_len);
}
if(wflag) {
if(write(f,&index,uindex_len) != uindex_len) {
goto quit;
}
}
close(f);
close(fdindex);
unlink(tempfile);
if(!(rename(tmpfile,tempfile))) {
if((fdindex = open(tempfile,O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE)) > 0) {
semrel(&Lock);
usputs(user->s,"Crunching successfully finished\n");
return;
}
}
quit:
errorstop(26);
semrel(&Lock);
return;
}
#ifdef XXX
static void near
connect_bbs(struct user *user)
{
char *address;
int addrlen;
int fd;
struct sockaddr *addr;
if ((address = connect_addr(user)) == NULLCHAR) return;
if (!(addr = build_sockaddr("unix:/tcp/.sockets/netcmd", &addrlen))) return;
if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) return;
if (connect(fd, addr, addrlen)) return;
if (fd != 0) dup2(fd, 0);
if (fd != 1) dup2(fd, 1);
if (fd != 2) dup2(fd, 2);
if (fd > 2) close(fd);
fdopen(0, "r+");
fdopen(1, "r+");
fdopen(2, "r+");
usprintf(user->s,"connect %s\n", address);
}
#endif
static void near
parse_command_line(struct user *user)
{
char *cp = user->line, *cp1;
int arglen = 0;
struct cmdtable *cmdp;
while(isspace(*cp)) {
cp++;
}
cp1 = cp;
log(user->s,9980,user->line);
if(*cp == '[') {
char *sid_features;
if(cp[strlen(cp) - 1] == ']') {
/* must be an SID */
user->sid = MBX_SID;
/* Now check to see if this is an RLI board.
* As usual, Hank does it a bit differently from the rest of the world.
*/
if(cp[1] == 'R' && strncmp(&cp[1],"li",2) == 0) {
/* [RLI] at a minimum */
user->sid |= MBX_RLI_SID;
}
/* Check to see if the BBS supports a kludge called "hierarchical
* routing designators."
*/
sid_features = strrchr(cp,'-');
if((sid_features != NULLCHAR)
&& (strlen(sid_features) > 3)
&& (strchr(sid_features,'h') != NULLCHAR)
&& (strchr(sid_features,'$') != NULLCHAR)) {
user->sid |= MBX_HIER_SID;
}
return;
}
}
while(*cp1 && !isspace(*cp1)) {
cp1++;
arglen++;
}
for(cmdp = cmdtable; cmdp->name; cmdp++) {
if(strnicmp(cmdp->name,cp,arglen) == 0) {
if(cmdp->argc && strchr(cp1,' ') == NULLCHAR) {
if(++user->errors >= 3) {
user->level = CLOSED;
}
usprintf(user->s,errstr,cmdp->name,cmdp->name);
} else {
user->errors = 0;
(cmdp->func)(user);
}
return;
}
}
/* Can't be a legal command */
usputs(user->s,"Unknown command. Type ? for help.\n");
if(user->level == BOX) {
user->level = CLOSED;
}
return;
}
static int near
setup_vars(void)
{
char *cp;
if(*myhostname) {
xfree(myhostname);
xfree(MYHOSTNAME);
}
cp = myhostname = strxdup(Hostname);
if((cp = strpbrk(myhostname,". @!")) != NULLCHAR) {
*cp = '\0';
}
MYHOSTNAME = strxdup(myhostname);
if((cp = strchr(MYHOSTNAME,'-')) != NULLCHAR) {
*cp = '\0';
}
strupr(MYHOSTNAME);
len_myhostname = strlen(myhostname);
len_MYHOSTNAME = strlen(MYHOSTNAME);
if(BbsUser == 0) {
char fname[MAXPATH];
sprintf(fname,"%s/%s",BBSwrkdir,Indexfile);
if((fdindex = open(fname,O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE)) < 1) {
errorstop(131);
return 0;
}
}
return ++BbsUser;
}
static void near
cleanup(struct user *user)
{
xfree(user->line);
xfree(user->name);
xfree(user);
if(--BbsUser < 1) {
close(fdindex);
fdindex = -1;
xfree(myhostname);
myhostname = NULLCHAR;
xfree(MYHOSTNAME);
MYHOSTNAME = NULLCHAR;
BbsUser = 0;
}
}
static struct user * near
get_seq(char *username,int flag)
{
char *cp;
struct user *u = mxallocw(sizeof(struct user));
if(access(BBSwrkdir,0)) {
mkdir(BBSwrkdir);
if(access(BBSwrkdir,0)) {
xfree(u);
return 0;
}
}
u->line = mxallocw(LINELEN);
cp = u->name = strxdup(username);
while(cp && isalnum(*cp)) {
cp++;
}
*cp = '\0';
if(flag) {
int fp = -1;
char fname[MAXPATH];
struct userinfo *uinfo = mxallocw(uinfo_len);
sprintf(fname,"%s/%s.rc",BBSwrkdir,username);
if((fp = open(fname,O_RDONLY | O_BINARY,S_IFREG | S_IREAD)) < 0
|| read(fp,uinfo,uinfo_len) != uinfo_len) {
*uinfo->mybbs = '\0';
uinfo->time = currtime;
uinfo->seq = 0;
}
if(fp != -1) {
close(fp);
}
u->info = uinfo;
}
return u;
}
static void near
put_seq(struct user *user)
{
int fp = -1;
char fname[MAXPATH];
sprintf(fname,"%s/%s.rc",BBSwrkdir,user->name);
unlink(fname); /* first delete the old file */
user->info->time = currtime;
if((fp = open(fname,O_CREAT | O_WRONLY | O_BINARY,S_IFREG | S_IWRITE)) < 0
|| write(fp,user->info,uinfo_len) != uinfo_len) {
/* if something is wrong, delete if something is on the disk */
unlink(fname);
}
if(fp != -1) {
close(fp);
}
}
int
recv_from_mail_or_news(FILE *data,char *from,char *to)
{
char *cp, distr[80], exp[80];
int fail = -1, from_priority = 0, state = 0;
int32 n = 0x7fffffffL;
struct mail *mail = alloc_mail();
struct user *user = get_seq(from,0);
if(!setup_vars()) {
return fail;
}
if((cp = strchr(user->name,'@')) != NULLCHAR) {
*cp = '\0';
}
*distr = '\0';
sprintf(mail->to,"%.*s",LEN+LEN,to);
while(fgets(user->line,LINELEN,data)) {
switch(state) {
case 0:
rip(user->line);
if(*user->line) {
if(from_priority < 1
&& !strncmp(user->line,"From ",5)
&& sscanf(user->line,"From %s",mail->from) == 1) {
from_priority = 1;
}
if(from_priority < 2
&& get_header_value(Hdrs[PATH],user->line,mail->from)) {
from_priority = 2;
}
if(from_priority < 3
&& get_header_value(Hdrs[FROM],user->line,mail->from)) {
from_priority = 3;
}
if(get_header_value(Hdrs[NEWSGROUPS],user->line,mail->newsgroup)) {
mail->flag = NEWS;
}
get_header_value(Hdrs[SUBJECT],user->line,mail->subject);
get_header_value(Hdrs[MSGID],user->line,mail->mid);
if(get_header_value(Hdrs[DISTRIBUTION],user->line,distr)) {
mail->flag = NEWS;
}
get_header_value(Hdrs[BULLID],user->line,mail->bid);
if(get_header_value(Hdrs[EXPIRE],user->line,exp)) {
/* */
}
} else {
state = 1;
}
break;
case 1:
if(!*user->line) {
break;
}
state = 2;
case 2:
append_line(mail,user->line);
}
if(n <= 0) {
break;
}
n -= strlen(user->line);
strtrim(user->line);
}
if(*mail->to && from_priority && state == 2) {
if(!strncmp(mail->to,"ampr.bbs.",9)) {
strcpy(mail->to,mail->to + 9);
}
if((cp = strchr(mail->to,',')) != NULLCHAR) {
*cp = 0;
}
if((cp = strrchr(mail->to,'.'))!= NULLCHAR) {
strcpy(mail->to, cp + 1);
}
if((cp = strchr(distr,',')) != NULLCHAR) {
*cp = 0;
}
if((cp = strrchr(distr,'.')) != NULLCHAR) {
strcpy(distr, cp + 1);
}
if(*distr) {
strcat(mail->to,"@");
strcat(mail->to,distr);
}
route_mail(mail,user,BBS);
fail = 0;
} else {
free_mail(mail);
}
cleanup(user);
return fail;
}
#include "mailbox.h"
int
dombbs(int argc,char **argv,void *p)
{
FILE *fp;
char line [MAXPATH];
struct mbx *m = (struct mbx *)p;
struct user *user = get_seq(m->name,1);
int oldf = setflush((user->s = m->user),'\n');
m->state = MBX_BBS;
if(!setup_vars()) {
return -1;
}
if(argc == 0x10) {
user->level = BOX;
}
if(user->level != BOX) {
if(m->perms & SYSOP_CMD) {
user->level = ROOT;
}
}
sprintf(line,"%s/%s.cfg",BBSwrkdir,user->name);
if((fp = Fopen(line,READ_TEXT,0,0)) != NULLFILE) {
while(fgets(user->line,LINELEN,fp) != NULL) {
parse_command_line(user);
}
Fclose(fp);
} else {
if(user->level != BOX) {
usprintf(user->s,"%s\nType '?' for help.\n",BBSversion);
}
}
for(; ; ) {
if(user->level == CLOSED) {
usputs(user->s,"BBS terminated\n");
break;
}
usprintf(user->s,user->level == BOX ? ">\n" : "%s-bbs>",myhostname);
if(mbxrecvline(m) == EOF) {
/* He closed on us */
goto quit;
}
strcpy(user->line,m->line);
if(!*user->line) {
continue;
}
parse_command_line(user);
}
quit:
put_seq(user);
xfree(user->info);
cleanup(user);
setflush(m->user,oldf);
return 0;
}
/* -------------------------- S&F - Subcmds ------------------------------- */
#ifdef AX25
/* Set the Info field of R: header (eg forward info "[Bath, Avon - WNOS]") */
int
dofinfo(int argc,char **argv,void *p)
{
if(argc < 2 && FInfo != NULLCHAR) {
tprintf("FBBS Info: %s\n", FInfo);
} else {
if(FInfo != NULLCHAR) {
xfree(FInfo);
}
FInfo = strxdup(argv[1]);
}
return 0;
}
/* Set Nic field of R: header (eg forward nic ".GB7IMB.#41.GBR.EU" */
int
dofnic(int argc,char **argv,void *p)
{
if(argc < 2 && FNic != NULLCHAR) {
tprintf("FNIC Id: %s\n", FNic);
} else {
if(FNic != NULLCHAR) {
xfree(FNic);
}
FNic = strxdup(argv[1]);
strupr(FNic);
}
return 0;
}
int
dofkick(int argc,char **argv,void *p)
{
return 0;
}
#endif
#endif